home *** CD-ROM | disk | FTP | other *** search
/ Mac Format 1995 June / MacFormat 25.iso / Shareware City / Developers / OutOfPhase1.1 Source / OutOfPhase Folder / SampleOscControl.c < prev    next >
Text File  |  1995-01-04  |  67KB  |  1,970 lines

  1. /* SampleOscControl.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "SampleOscControl.h"
  31. #include "64BitMath.h"
  32. #include "Multisampler.h"
  33. #include "EnvelopeState.h"
  34. #include "Envelope.h"
  35. #include "LFOGenerator.h"
  36. #include "LFOListSpecifier.h"
  37. #include "SampleConsts.h"
  38. #include "Memory.h"
  39. #include "OscillatorSpecifier.h"
  40. #include "ErrorDaemon.h"
  41.  
  42.  
  43. #if !MEMDEBUG && DEBUG
  44.     #undef PRNGCHK
  45.     #define PRNGCHK(x,y,z) ((void)0)
  46. #endif
  47.  
  48.  
  49. /* prototypes for fast playback routines */
  50. static void                        Sample_MonoOut_MonoSamp_8BitIn_NoTime(SampleStateRec* State,
  51.                                                 long SampleCount, largefixedsigned* RawBuffer);
  52. static void                        Sample_StereoOut_MonoSamp_8BitIn_NoTime(SampleStateRec* State,
  53.                                                 long SampleCount, largefixedsigned* RawBuffer);
  54. static void                        Sample_MonoOut_StereoSamp_8BitIn_NoTime(SampleStateRec* State,
  55.                                                 long SampleCount, largefixedsigned* RawBuffer);
  56. static void                        Sample_StereoOut_StereoSamp_8BitIn_NoTime(SampleStateRec* State,
  57.                                                 long SampleCount, largefixedsigned* RawBuffer);
  58.  
  59. static void                        Sample_MonoOut_MonoSamp_16BitIn_NoTime(SampleStateRec* State,
  60.                                                 long SampleCount, largefixedsigned* RawBuffer);
  61. static void                        Sample_StereoOut_MonoSamp_16BitIn_NoTime(SampleStateRec* State,
  62.                                                 long SampleCount, largefixedsigned* RawBuffer);
  63. static void                        Sample_MonoOut_StereoSamp_16BitIn_NoTime(SampleStateRec* State,
  64.                                                 long SampleCount, largefixedsigned* RawBuffer);
  65. static void                        Sample_StereoOut_StereoSamp_16BitIn_NoTime(SampleStateRec* State,
  66.                                                 long SampleCount, largefixedsigned* RawBuffer);
  67.  
  68. static void                        Sample_MonoOut_MonoSamp_8BitIn_YesTime(SampleStateRec* State,
  69.                                                 long SampleCount, largefixedsigned* RawBuffer);
  70. static void                        Sample_StereoOut_MonoSamp_8BitIn_YesTime(SampleStateRec* State,
  71.                                                 long SampleCount, largefixedsigned* RawBuffer);
  72. static void                        Sample_MonoOut_StereoSamp_8BitIn_YesTime(SampleStateRec* State,
  73.                                                 long SampleCount, largefixedsigned* RawBuffer);
  74. static void                        Sample_StereoOut_StereoSamp_8BitIn_YesTime(SampleStateRec* State,
  75.                                                 long SampleCount, largefixedsigned* RawBuffer);
  76.  
  77. static void                        Sample_MonoOut_MonoSamp_16BitIn_YesTime(SampleStateRec* State,
  78.                                                 long SampleCount, largefixedsigned* RawBuffer);
  79. static void                        Sample_StereoOut_MonoSamp_16BitIn_YesTime(SampleStateRec* State,
  80.                                                 long SampleCount, largefixedsigned* RawBuffer);
  81. static void                        Sample_MonoOut_StereoSamp_16BitIn_YesTime(SampleStateRec* State,
  82.                                                 long SampleCount, largefixedsigned* RawBuffer);
  83. static void                        Sample_StereoOut_StereoSamp_16BitIn_YesTime(SampleStateRec* State,
  84.                                                 long SampleCount, largefixedsigned* RawBuffer);
  85.  
  86. static void                        Sample_NoOutput(SampleStateRec* State,
  87.                                                 long SampleCount, largefixedsigned* RawBuffer);
  88.  
  89.  
  90. /* this is used for loop control */
  91. typedef enum
  92.     {
  93.         eRepeatingLoop1 EXECUTE(= -18734),
  94.         eRepeatingLoop2,
  95.         eRepeatingLoop3,
  96.         eNoLoop,
  97.         eSampleFinished
  98.     } LoopType;
  99.  
  100.  
  101. /* sample oscillator template information record */
  102. struct SampleTemplateRec
  103.     {
  104.         /* source information for the sample */
  105.         MultiSampleRec*                SampleSourceSelector;
  106.  
  107.         /* sampling rate for final output */
  108.         long                                    FinalOutputSamplingRate;
  109.         /* number of envelope updates per second */
  110.         float                                    EnvelopeTicksPerSecond;
  111.  
  112.         /* values for scaling the frequency of something.  if we were really serious about */
  113.         /* this, we'd traverse all of the oscillators with integral multiples or harmonic */
  114.         /* fractions of the pitch & set their differentials to the same precision as the */
  115.         /* worst oscillator so that they would all stay in sync as time progressed. */
  116.         float                                    FrequencyMultiplier;
  117.         /* this is added after the frequency multiplier is applied */
  118.         float                                    FrequencyAdder;
  119.  
  120.         /* stereo status */
  121.         NumChannelsType                StereoPlayback;
  122.         /* time interpolation flag */
  123.         MyBoolean                            InterpolateThroughTime;
  124.         /* inter-wave interpolation flag */
  125.         MyBoolean                            InterpolateAcrossWaves; /* not used now -- for future use */
  126.  
  127.         /* envelope templates */
  128.         EnvelopeRec*                    LoudnessEnvelopeTemplate;
  129.         LFOListSpecRec*                LoudnessLFOTemplate;
  130.  
  131.         /* miscellaneous control parameters */
  132.         float                                    StereoBias;
  133.         float                                    TimeDisplacement;
  134.         float                                    OverallOscillatorLoudness;
  135.  
  136.         /* error logging facility */
  137.         ErrorDaemonRec*                ErrorDaemon;
  138.  
  139.         /* template for the pitch displacement LFO */
  140.         LFOListSpecRec*                PitchLFOTemplate;
  141.  
  142.         /* link for list control */
  143.         SampleTemplateRec*        Next;
  144.     };
  145.  
  146.  
  147. /* sample oscillator state record */
  148. struct SampleStateRec
  149.     {
  150.         /* current sample position into the array */
  151.         LongLongRec                        SamplePosition; /* 32-bit fixed point */
  152.         /* current increment value for the sample position */
  153.         LongLongRec                        SamplePositionDifferential; /* 32-bit fixed point */
  154.         /* envelope tick countdown for pre-start time */
  155.         long                                    PreStartCountdown;
  156.  
  157.         /* function for generating a bunch of sample points */
  158.         void                                    (*SampleGenSamples)(SampleStateRec* State,
  159.                                                         long SampleCount, largefixedsigned* RawBuffer);
  160.  
  161.         /* number of frames in the sample */
  162.         long                                    NumFrames;
  163.         /* sample data pointer.  for mono, it is just an array.  for stereo, the */
  164.         /* samples are interleaved, left channel first */
  165.         void*                                    Data;
  166.         /* number of bits in the data for the sample */
  167.         NumBitsType                        NumBits;
  168.         /* stereo or mono sample */
  169.         NumChannelsType                NumChannels;
  170.  
  171.         /* control parameters for the sample */
  172.         float                                    NaturalFrequency;
  173.         long                                    SamplingRate;
  174.         long                                    OriginPoint;
  175.         long                                    Loop1Start;
  176.         long                                    Loop2Start;
  177.         long                                    Loop3Start;
  178.         long                                    Loop1End;
  179.         long                                    Loop2End;
  180.         long                                    Loop3End;
  181.         /* state information for the current position */
  182.         LoopType                            LoopState; /* which loop is running */
  183.         long                                    CurrentLoopLength; /* current loop length (end - start) */
  184.         long                                    CurrentLoopEnd; /* current loop/total end point */
  185.  
  186.         /* NOTE:  either OverallLoudness or Left/RightLoudness are used, but not both */
  187.         /* current overall loudness for oscillator */
  188.         FastFixedType                    OverallLoudness; /* 15-bit fixed point, 0..1 */
  189.         /* left channel loudness */
  190.         FastFixedType                    LeftLoudness; /* 15-bit fixed point, 0..1 */
  191.         /* right channel loudness */
  192.         FastFixedType                    RightLoudness; /* 15-bit fixed point, 0..1 */
  193.         /* panning position for splitting envelope generator into stereo channels */
  194.         /* 0 = left channel, 0.5 = middle, 1 = right channel */
  195.         FastFixedType                    Panning; /* 15-bit fixed point, 0..1 */
  196.         /* envelope that is generating the loudness information */
  197.         EvalEnvelopeRec*            SampleLoudnessEnvelope;
  198.         /* LFO generators modifying the output of the loudness envelope generator */
  199.         LFOGenRec*                        LoudnessLFOGenerator;
  200.  
  201.         /* this flag is True if the sample data was defined at the specified pitch */
  202.         /* (and the sample vectors are thus valid) or False if there is no sample */
  203.         /* at this pitch (and the arrays are invalid) */
  204.         MyBoolean                            SampleWasDefined;
  205.  
  206.         /* this field contains the overall volume scaling for everything so that we */
  207.         /* can treat the envelopes as always going between 0 and 1. */
  208.         float                                    NoteLoudnessScaling;
  209.  
  210.         /* this calculates the differential values for periodic pitch displacements */
  211.         LFOGenRec*                        PitchLFO;
  212.         /* pitch lfo startup counter; negative = expired */
  213.         long                                    PitchLFOStartCountdown;
  214.  
  215.         /* static information for the sample */
  216.         SampleTemplateRec            Template; /* a copy of the data */
  217.  
  218.         /* link for list control */
  219.         SampleStateRec*                Next;
  220.     };
  221.  
  222.  
  223.  
  224.  
  225. static SampleTemplateRec*                SampleTemplateFreeList = NIL;
  226. static SampleStateRec*                    SampleStateFreeList = NIL;
  227.  
  228.  
  229. /* get rid of all cached memory for state or template records */
  230. void                                    FlushSampleOscControl(void)
  231.     {
  232.         while (SampleTemplateFreeList != NIL)
  233.             {
  234.                 SampleTemplateRec*    Temp;
  235.  
  236.                 Temp = SampleTemplateFreeList;
  237.                 SampleTemplateFreeList = SampleTemplateFreeList->Next;
  238.                 ReleasePtr((char*)Temp);
  239.             }
  240.  
  241.         while (SampleStateFreeList != NIL)
  242.             {
  243.                 SampleStateRec*            Temp;
  244.  
  245.                 Temp = SampleStateFreeList;
  246.                 SampleStateFreeList = SampleStateFreeList->Next;
  247.                 ReleasePtr((char*)Temp);
  248.             }
  249.     }
  250.  
  251.  
  252. #if DEBUG
  253. static void                        CheckValidSampleTemplate(SampleTemplateRec* Object)
  254.     {
  255.         SampleTemplateRec*    Scan;
  256.  
  257.         Scan = SampleTemplateFreeList;
  258.         while (Scan != NIL)
  259.             {
  260.                 if (Scan == Object)
  261.                     {
  262.                         PRERR(ForceAbort,"CheckValidSampleTemplate:  template is on free list");
  263.                     }
  264.                 Scan = Scan->Next;
  265.             }
  266.     }
  267. #else
  268. #define CheckValidSampleTemplate(x) ((void)0)
  269. #endif
  270.  
  271.  
  272. #if DEBUG
  273. static void                        CheckValidSampleState(SampleStateRec* Object)
  274.     {
  275.         SampleStateRec*            Scan;
  276.  
  277.         Scan = SampleStateFreeList;
  278.         while (Scan != NIL)
  279.             {
  280.                 if (Scan == Object)
  281.                     {
  282.                         PRERR(ForceAbort,"CheckValidSampleState:  state is on free list");
  283.                     }
  284.                 Scan = Scan->Next;
  285.             }
  286.     }
  287. #else
  288. #define CheckValidSampleState(x) ((void)0)
  289. #endif
  290.  
  291.  
  292. /* perform one envelope update cycle */
  293. void                                    UpdateSampleEnvelopes(SampleStateRec* State)
  294.     {
  295.         FastFixedType                Temp;
  296.  
  297.         CheckPtrExistence(State);
  298.         CheckValidSampleState(State);
  299.  
  300.         /* this is for the benefit of resampling only -- envelope generators do their */
  301.         /* own pre-origin sequencing */
  302.         if (State->PreStartCountdown > 0)
  303.             {
  304.                 State->PreStartCountdown -= 1;
  305.             }
  306.  
  307.         Temp = State->NoteLoudnessScaling * LFOGenUpdateCycle(State->LoudnessLFOGenerator,
  308.             EnvelopeUpdate(State->SampleLoudnessEnvelope));
  309.         /* fast fixed has a very narrow range, so overflow can't be permitted: */
  310.         /* 15x15->30 bits, with 2 extra bits; we use one for sign and the other */
  311.         /* to permit the representation of 1 and -1. */
  312.         if (State->Template.StereoPlayback == eSampleMono)
  313.             {
  314.                 if (Temp < - Int2FastFixed(1))
  315.                     {
  316.                         ErrorDaemonReportClamping(State->Template.ErrorDaemon,
  317.                             - FastFixed2Float(Temp));
  318.                         Temp = - Int2FastFixed(1);
  319.                     }
  320.                 else if (Temp > Int2FastFixed(1))
  321.                     {
  322.                         ErrorDaemonReportClamping(State->Template.ErrorDaemon,
  323.                             FastFixed2Float(Temp));
  324.                         Temp = Int2FastFixed(1);
  325.                     }
  326.                 State->OverallLoudness = Temp;
  327.             }
  328.          else
  329.             {
  330.                 FastFixedType                LeftVolumeScaling;
  331.                 FastFixedType                RightVolumeScaling;
  332.                 FastFixedType                MaxVolScaling;
  333.                 FastFixedType                MaxTemp;
  334.  
  335.                 LeftVolumeScaling = FastFixedTimesFastFixedToFastFixed(Double2FastFixed(0.5),
  336.                     Int2FastFixed(1) - State->Panning);
  337.                 RightVolumeScaling = FastFixedTimesFastFixedToFastFixed(Double2FastFixed(0.5),
  338.                     Int2FastFixed(1) + State->Panning);
  339.  
  340.                 if (((LeftVolumeScaling >= 0) ? LeftVolumeScaling : (- LeftVolumeScaling))
  341.                     > ((RightVolumeScaling >= 0) ? RightVolumeScaling : (- RightVolumeScaling)))
  342.                     {
  343.                         MaxVolScaling = ((LeftVolumeScaling >= 0)
  344.                             ? LeftVolumeScaling : (- LeftVolumeScaling));
  345.                     }
  346.                  else
  347.                     {
  348.                         MaxVolScaling = ((RightVolumeScaling >= 0)
  349.                             ? RightVolumeScaling : (- RightVolumeScaling));
  350.                     }
  351.                 MaxTemp = Double2FastFixed((float)1 / FastFixed2Float(MaxVolScaling));
  352.                 if (Temp < - MaxTemp)
  353.                     {
  354.                         ErrorDaemonReportClamping(State->Template.ErrorDaemon,
  355.                             - FastFixed2Float(Temp) / FastFixed2Float(MaxTemp));
  356.                         Temp = - MaxTemp;
  357.                     }
  358.                 else if (Temp > MaxTemp)
  359.                     {
  360.                         ErrorDaemonReportClamping(State->Template.ErrorDaemon,
  361.                             FastFixed2Float(Temp) / FastFixed2Float(MaxTemp));
  362.                         Temp = MaxTemp;
  363.                     }
  364.  
  365.                 State->LeftLoudness = FastFixedTimesFastFixedToFastFixed(
  366.                     LeftVolumeScaling,Temp);
  367.                 State->RightLoudness = FastFixedTimesFastFixedToFastFixed(
  368.                     RightVolumeScaling,Temp);
  369.             }
  370.     }
  371.  
  372.  
  373. /* dispose of the sample state record */
  374. void                                    DisposeSampleState(SampleStateRec* State)
  375.     {
  376.         CheckPtrExistence(State);
  377.         CheckValidSampleState(State);
  378.  
  379.         DisposeEnvelopeStateRecord(State->SampleLoudnessEnvelope);
  380.         DisposeLFOGenerator(State->LoudnessLFOGenerator);
  381.         DisposeLFOGenerator(State->PitchLFO);
  382.  
  383.         State->Next = SampleStateFreeList;
  384.         SampleStateFreeList = State;
  385.     }
  386.  
  387.  
  388. /* dispose of the sample information template */
  389. void                                    DisposeSampleTemplate(SampleTemplateRec* Template)
  390.     {
  391.         CheckPtrExistence(Template);
  392.         CheckValidSampleTemplate(Template);
  393.  
  394.         DisposeMultisample(Template->SampleSourceSelector);
  395.  
  396.         Template->Next = SampleTemplateFreeList;
  397.         SampleTemplateFreeList = Template;
  398.     }
  399.  
  400.  
  401. /* create a new sample template */
  402. SampleTemplateRec*        NewSampleTemplate(struct OscillatorRec* Oscillator,
  403.                                                 float EnvelopeTicksPerSecond, long SamplingRate,
  404.                                                 MyBoolean Stereo, MyBoolean TimeInterp, MyBoolean WaveInterp,
  405.                                                 ErrorDaemonRec* ErrorDaemon)
  406.     {
  407.         SampleTemplateRec*    Template;
  408.  
  409.         CheckPtrExistence(ErrorDaemon);
  410.         CheckPtrExistence(Oscillator);
  411.         ERROR(OscillatorGetWhatKindItIs(Oscillator) != eOscillatorSampled,PRERR(ForceAbort,
  412.             "NewSampleTemplate:  oscillator is not a sample"));
  413.  
  414.         if (SampleTemplateFreeList != NIL)
  415.             {
  416.                 Template = SampleTemplateFreeList;
  417.                 SampleTemplateFreeList = SampleTemplateFreeList->Next;
  418.             }
  419.          else
  420.             {
  421.                 Template = (SampleTemplateRec*)AllocPtrCanFail(sizeof(SampleTemplateRec),
  422.                     "SampleTemplateRec");
  423.                 if (Template == NIL)
  424.                     {
  425.                         return NIL;
  426.                     }
  427.             }
  428.         EXECUTE(Template->Next = (SampleTemplateRec*)0x81818181;)
  429.  
  430.         Template->SampleSourceSelector = NewMultisampleSample(
  431.             OscillatorGetSampleIntervalList(Oscillator));
  432.         if (Template->SampleSourceSelector == NIL)
  433.             {
  434.              FailurePoint1:
  435.                 Template->Next = SampleTemplateFreeList;
  436.                 SampleTemplateFreeList = Template;
  437.                 return NIL;
  438.             }
  439.  
  440.         Template->FinalOutputSamplingRate = SamplingRate;
  441.         Template->EnvelopeTicksPerSecond = EnvelopeTicksPerSecond;
  442.  
  443.         /* it might be better to handle divisor and multiplier separately -- we would */
  444.         /* want to do that if we were trying to guarantee that all harmonic */
  445.         /* oscillators ran in lock-step */
  446.         Template->FrequencyMultiplier = OscillatorGetFrequencyMultiplier(Oscillator)
  447.             / OscillatorGetFrequencyDivisor(Oscillator);
  448.         Template->FrequencyAdder = OscillatorGetFrequencyAdder(Oscillator);
  449.  
  450.         Template->StereoBias = OscillatorGetStereoBias(Oscillator);
  451.         Template->TimeDisplacement = OscillatorGetTimeDisplacement(Oscillator);
  452.         Template->OverallOscillatorLoudness = OscillatorGetOutputLoudness(Oscillator);
  453.  
  454.         if (Stereo)
  455.             {
  456.                 Template->StereoPlayback = eSampleStereo;
  457.             }
  458.          else
  459.             {
  460.                 Template->StereoPlayback = eSampleMono;
  461.             }
  462.         Template->InterpolateThroughTime = TimeInterp;
  463.         Template->InterpolateAcrossWaves = WaveInterp;
  464.  
  465.         /* these are just references */
  466.         Template->LoudnessEnvelopeTemplate = OscillatorGetLoudnessEnvelope(Oscillator);
  467.         Template->LoudnessLFOTemplate = OscillatorGetLoudnessLFOList(Oscillator);
  468.  
  469.         /* more references */
  470.         Template->ErrorDaemon = ErrorDaemon;
  471.         Template->PitchLFOTemplate = GetOscillatorFrequencyLFOList(Oscillator);
  472.  
  473.         return Template;
  474.     }
  475.  
  476.  
  477. /* create a new sample state object. */
  478. SampleStateRec*                NewSampleState(SampleTemplateRec* Template,
  479.                                                 float FreqForMultisampling, float Accent1, float Accent2,
  480.                                                 float Accent3, float Accent4, float Loudness, float HurryUp,
  481.                                                 long* PreOriginTimeOut, float StereoPosition,
  482.                                                 float InitialFrequency, float PitchDisplacementDepthLimit,
  483.                                                 float PitchDisplacementRateLimit,
  484.                                                 long PitchDisplacementStartPoint)
  485.     {
  486.         SampleStateRec*            State;
  487.         long                                MaxPreOrigin;
  488.         long                                OnePreOrigin;
  489.         double                            NaturalFreqTemp;
  490.  
  491.         CheckPtrExistence(Template);
  492.         CheckValidSampleTemplate(Template);
  493.  
  494.         if (SampleStateFreeList != NIL)
  495.             {
  496.                 State = SampleStateFreeList;
  497.                 SampleStateFreeList = SampleStateFreeList->Next;
  498.             }
  499.          else
  500.             {
  501.                 State = (SampleStateRec*)AllocPtrCanFail(sizeof(SampleStateRec),
  502.                     "SampleStateRec");
  503.                 if (State == NIL)
  504.                     {
  505.                      FailurePoint1:
  506.                         return NIL;
  507.                     }
  508.             }
  509.         EXECUTE(State->Next = (SampleStateRec*)0x81818181;)
  510.  
  511.         State->Template = *Template;
  512.  
  513.         MaxPreOrigin = 0;
  514.  
  515.         Double2LongLong(0,&(State->SamplePosition));
  516.         /* State->SamplePositionDifferential is specified in a separate call */
  517.  
  518.         State->NoteLoudnessScaling = Loudness * Template->OverallOscillatorLoudness;
  519.  
  520.         State->SampleWasDefined = GetMultisampleReferenceSample(
  521.             Template->SampleSourceSelector,FreqForMultisampling,&(State->Data),
  522.             &(State->NumFrames),&(State->NumBits),&(State->NumChannels),&(State->Loop1Start),
  523.             &(State->Loop1End),&(State->Loop2Start),&(State->Loop2End),&(State->Loop3Start),
  524.             &(State->Loop3End),&(State->OriginPoint),&NaturalFreqTemp,&(State->SamplingRate));
  525.  
  526.         if (State->SampleWasDefined && (State->NumFrames > 0))
  527.             {
  528.                 /* copy value over */
  529.                 State->NaturalFrequency = NaturalFreqTemp;
  530.  
  531.                 /* bounds checking */
  532.                 if (State->Loop1Start < 0)
  533.                     {
  534.                         State->Loop1Start = 0;
  535.                     }
  536.                 if (State->Loop1End > State->NumFrames - 1)
  537.                     {
  538.                         State->Loop1End = State->NumFrames - 1;
  539.                     }
  540.                 if (State->Loop1End < State->Loop1Start)
  541.                     {
  542.                         State->Loop1End = State->Loop1Start;
  543.                     }
  544.                 if (State->Loop2Start < 0)
  545.                     {
  546.                         State->Loop2Start = 0;
  547.                     }
  548.                 if (State->Loop2End > State->NumFrames - 1)
  549.                     {
  550.                         State->Loop2End = State->NumFrames - 1;
  551.                     }
  552.                 if (State->Loop2End < State->Loop2Start)
  553.                     {
  554.                         State->Loop2End = State->Loop2Start;
  555.                     }
  556.                 if (State->Loop3Start < 0)
  557.                     {
  558.                         State->Loop3Start = 0;
  559.                     }
  560.                 if (State->Loop3End > State->NumFrames - 1)
  561.                     {
  562.                         State->Loop3End = State->NumFrames - 1;
  563.                     }
  564.                 if (State->Loop3End < State->Loop3Start)
  565.                     {
  566.                         State->Loop3End = State->Loop3Start;
  567.                     }
  568.  
  569.                 /* set the initial state */
  570.                 if (State->Loop1Start != State->Loop1End)
  571.                     {
  572.                         State->LoopState = eRepeatingLoop1;
  573.                         State->CurrentLoopEnd = State->Loop1End;
  574.                         State->CurrentLoopLength = State->Loop1End - State->Loop1Start;
  575.                     }
  576.                 else if (State->Loop2Start != State->Loop2End)
  577.                     {
  578.                         State->LoopState = eRepeatingLoop2;
  579.                         State->CurrentLoopEnd = State->Loop2End;
  580.                         State->CurrentLoopLength = State->Loop2End - State->Loop2Start;
  581.                     }
  582.                 else if (State->Loop3Start != State->Loop3End)
  583.                     {
  584.                         State->LoopState = eRepeatingLoop3;
  585.                         State->CurrentLoopEnd = State->Loop3End;
  586.                         State->CurrentLoopLength = State->Loop3End - State->Loop3Start;
  587.                     }
  588.                 else
  589.                     {
  590.                         State->LoopState = eNoLoop;
  591.                         State->CurrentLoopEnd = State->NumFrames;
  592.                         State->CurrentLoopLength = 0;
  593.                     }
  594.  
  595.                 /* compute how much time to wait before starting sample playback.  this */
  596.                 /* is INDEPENDENT of the envelope starting points; the envelope generator setup */
  597.                 /* handles origin alignment on its own. */
  598.                 /* this number will assume the origin starts NOW.  the fixup routine will */
  599.                 /* add some number to this so that the origin is properly determined. */
  600.                 /* if the countdown is still negative, then the sample will sound like it */
  601.                 /* is starting late.  the user can fix this by increasing the scanning gap. */
  602.                 State->PreStartCountdown = - (
  603.                     ((((float)State->OriginPoint / ((InitialFrequency
  604.                         * Template->FrequencyMultiplier + Template->FrequencyAdder)
  605.                         / State->NaturalFrequency)) / State->SamplingRate)
  606.                         - Template->TimeDisplacement)
  607.                     * Template->EnvelopeTicksPerSecond + 0.5);
  608.                 if (- State->PreStartCountdown > MaxPreOrigin)
  609.                     {
  610.                         MaxPreOrigin = - State->PreStartCountdown;
  611.                     }
  612.             }
  613.          else
  614.             {
  615.                 /* no playback */
  616.                 State->LoopState = eSampleFinished;
  617.             }
  618.  
  619.         /* State->SampleWasDefined: */
  620.         /*   if there is no sample defined for the current pitch, then we don't */
  621.         /*   bother generating any data */
  622.         /* State->NumFrames > 0: */
  623.         /*   if there is no data in the sample, then don't access the array */
  624.         if (State->SampleWasDefined && (State->NumFrames > 0))
  625.             {
  626.                 if (Template->StereoPlayback == eSampleStereo) /* this is output stereo */
  627.                     {
  628.                         if (State->NumBits == eSample16bit)
  629.                             {
  630.                                 if (State->NumChannels == eSampleStereo) /* this is sample data stereo */
  631.                                     {
  632.                                         if (Template->InterpolateThroughTime)
  633.                                             {
  634.                                                 State->SampleGenSamples = Sample_StereoOut_StereoSamp_16BitIn_YesTime;
  635.                                             }
  636.                                          else
  637.                                             {
  638.                                                 State->SampleGenSamples = Sample_StereoOut_StereoSamp_16BitIn_NoTime;
  639.                                             }
  640.                                     }
  641.                                  else /* sample data mono */
  642.                                     {
  643.                                         if (Template->InterpolateThroughTime)
  644.                                             {
  645.                                                 State->SampleGenSamples = Sample_StereoOut_MonoSamp_16BitIn_YesTime;
  646.                                             }
  647.                                          else
  648.                                             {
  649.                                                 State->SampleGenSamples = Sample_StereoOut_MonoSamp_16BitIn_NoTime;
  650.                                             }
  651.                                     }
  652.                             }
  653.                          else /* output 8-bit */
  654.                             {
  655.                                 if (State->NumChannels == eSampleStereo) /* this is sample data stereo */
  656.                                     {
  657.                                         if (Template->InterpolateThroughTime)
  658.                                             {
  659.                                                 State->SampleGenSamples = Sample_StereoOut_StereoSamp_8BitIn_YesTime;
  660.                                             }
  661.                                          else
  662.                                             {
  663.                                                 State->SampleGenSamples = Sample_StereoOut_StereoSamp_8BitIn_NoTime;
  664.                                             }
  665.                                     }
  666.                                  else /* mono sample data */
  667.                                     {
  668.                                         if (Template->InterpolateThroughTime)
  669.                                             {
  670.                                                 State->SampleGenSamples = Sample_StereoOut_MonoSamp_8BitIn_YesTime;
  671.                                             }
  672.                                          else
  673.                                             {
  674.                                                 State->SampleGenSamples = Sample_StereoOut_MonoSamp_8BitIn_NoTime;
  675.                                             }
  676.                                     }
  677.                             }
  678.                     }
  679.                  else /* output mono */
  680.                     {
  681.                         if (State->NumBits == eSample16bit)
  682.                             {
  683.                                 if (State->NumChannels == eSampleStereo) /* this is sample data stereo */
  684.                                     {
  685.                                         if (Template->InterpolateThroughTime)
  686.                                             {
  687.                                                 State->SampleGenSamples = Sample_MonoOut_StereoSamp_16BitIn_YesTime;
  688.                                             }
  689.                                          else
  690.                                             {
  691.                                                 State->SampleGenSamples = Sample_MonoOut_StereoSamp_16BitIn_NoTime;
  692.                                             }
  693.                                     }
  694.                                  else /* sample data mono */
  695.                                     {
  696.                                         if (Template->InterpolateThroughTime)
  697.                                             {
  698.                                                 State->SampleGenSamples = Sample_MonoOut_MonoSamp_16BitIn_YesTime;
  699.                                             }
  700.                                          else
  701.                                             {
  702.                                                 State->SampleGenSamples = Sample_MonoOut_MonoSamp_16BitIn_NoTime;
  703.                                             }
  704.                                     }
  705.                             }
  706.                          else /* 8-bit */
  707.                             {
  708.                                 if (State->NumChannels == eSampleStereo) /* this is sample data stereo */
  709.                                     {
  710.                                         if (Template->InterpolateThroughTime)
  711.                                             {
  712.                                                 State->SampleGenSamples = Sample_MonoOut_StereoSamp_8BitIn_YesTime;
  713.                                             }
  714.                                          else
  715.                                             {
  716.                                                 State->SampleGenSamples = Sample_MonoOut_StereoSamp_8BitIn_NoTime;
  717.                                             }
  718.                                     }
  719.                                  else /* sample data mono */
  720.                                     {
  721.                                         if (Template->InterpolateThroughTime)
  722.                                             {
  723.                                                 State->SampleGenSamples = Sample_MonoOut_MonoSamp_8BitIn_YesTime;
  724.                                             }
  725.                                          else
  726.                                             {
  727.                                                 State->SampleGenSamples = Sample_MonoOut_MonoSamp_8BitIn_NoTime;
  728.                                             }
  729.                                     }
  730.                             }
  731.                     }
  732.             }
  733.          else
  734.             {
  735.                 State->SampleGenSamples = Sample_NoOutput;
  736.             }
  737.  
  738.         /* State->OverallLoudness, State->LeftLoudness, State->RightLoudness */
  739.         /* are determined by the envelope update */
  740.         StereoPosition += Template->StereoBias;
  741.         if (StereoPosition < -1)
  742.             {
  743.                 StereoPosition = -1;
  744.             }
  745.         else if (StereoPosition > 1)
  746.             {
  747.                 StereoPosition = 1;
  748.             }
  749.         State->Panning = Double2FastFixed(StereoPosition);
  750.         State->SampleLoudnessEnvelope = NewEnvelopeStateRecord(
  751.             Template->LoudnessEnvelopeTemplate,Accent1,Accent2,Accent3,Accent4,
  752.             InitialFrequency,1,HurryUp,Template->EnvelopeTicksPerSecond,&OnePreOrigin);
  753.         if (State->SampleLoudnessEnvelope == NIL)
  754.             {
  755.              FailurePoint2:
  756.                 State->Next = SampleStateFreeList;
  757.                 SampleStateFreeList = State;
  758.                 goto FailurePoint1;
  759.             }
  760.         if (OnePreOrigin > MaxPreOrigin)
  761.             {
  762.                 MaxPreOrigin = OnePreOrigin;
  763.             }
  764.         State->LoudnessLFOGenerator = NewLFOGenerator(Template->LoudnessLFOTemplate,
  765.             &OnePreOrigin,Accent1,Accent2,Accent3,Accent4,InitialFrequency,HurryUp,
  766.             Template->EnvelopeTicksPerSecond,1,1,FreqForMultisampling);
  767.         /* I forgot what to pass in for the last 2 parameters */
  768.         if (State->LoudnessLFOGenerator == NIL)
  769.             {
  770.              FailurePoint3:
  771.                 DisposeEnvelopeStateRecord(State->SampleLoudnessEnvelope);
  772.                 goto FailurePoint2;
  773.             }
  774.         if (OnePreOrigin > MaxPreOrigin)
  775.             {
  776.                 MaxPreOrigin = OnePreOrigin;
  777.             }
  778.         State->PitchLFO = NewLFOGenerator(Template->PitchLFOTemplate,
  779.             &OnePreOrigin,Accent1,Accent2,Accent3,Accent4,InitialFrequency,HurryUp,
  780.             Template->EnvelopeTicksPerSecond,PitchDisplacementDepthLimit,
  781.             PitchDisplacementRateLimit,FreqForMultisampling);
  782.         if (State->PitchLFO == NIL)
  783.             {
  784.              FailurePoint4:
  785.                 DisposeLFOGenerator(State->LoudnessLFOGenerator);
  786.                 goto FailurePoint3;
  787.             }
  788.         if (OnePreOrigin > MaxPreOrigin)
  789.             {
  790.                 MaxPreOrigin = OnePreOrigin;
  791.             }
  792.         State->PitchLFOStartCountdown = PitchDisplacementStartPoint;
  793.  
  794.         *PreOriginTimeOut = MaxPreOrigin;
  795.         return State;
  796.     }
  797.  
  798.  
  799. /* fix up pre-origin time for the sample state object */
  800. void                                    FixUpSampleStatePreOrigin(SampleStateRec* State,
  801.                                                 long ActualPreOrigin)
  802.     {
  803.         CheckPtrExistence(State);
  804.         CheckValidSampleState(State);
  805.  
  806.         EnvelopeStateFixUpInitialDelay(State->SampleLoudnessEnvelope,ActualPreOrigin);
  807.         LFOGeneratorFixEnvelopeOrigins(State->LoudnessLFOGenerator,ActualPreOrigin);
  808.         LFOGeneratorFixEnvelopeOrigins(State->PitchLFO,ActualPreOrigin);
  809.  
  810.         State->PreStartCountdown += ActualPreOrigin;
  811.     }
  812.  
  813.  
  814. /* set a new frequency for a state object.  used for portamento */
  815. /* and modulation of frequency (vibrato) */
  816. void                                    SampleStateNewFrequency(SampleStateRec* State,
  817.                                                 float NewFrequencyHertz)
  818.     {
  819.         double                            Differential;
  820.  
  821.         CheckPtrExistence(State);
  822.         CheckValidSampleState(State);
  823.         if (State->PitchLFOStartCountdown > 0)
  824.             {
  825.                 State->PitchLFOStartCountdown -= 1;
  826.             }
  827.          else
  828.             {
  829.                 /* do some pitch stuff */
  830.                 NewFrequencyHertz = FastFixed2Float(LFOGenUpdateCycle(State->PitchLFO,
  831.                     Double2FastFixed(NewFrequencyHertz)));
  832.             }
  833.         Differential = ((NewFrequencyHertz * State->Template.FrequencyMultiplier
  834.             + State->Template.FrequencyAdder) / State->NaturalFrequency)
  835.             / State->Template.FinalOutputSamplingRate
  836.             * State->SamplingRate;
  837.         if (Differential < 0)
  838.             {
  839.                 Differential = 0;
  840.             }
  841.         Double2LongLong(Differential,&(State->SamplePositionDifferential));
  842.     }
  843.  
  844.  
  845. /* send a key-up signal to one of the oscillators */
  846. void                                    SampleKeyUpSustain1(SampleStateRec* State)
  847.     {
  848.         CheckPtrExistence(State);
  849.         CheckValidSampleState(State);
  850.  
  851.         LFOGeneratorKeyUpSustain1(State->LoudnessLFOGenerator);
  852.         EnvelopeKeyUpSustain1(State->SampleLoudnessEnvelope);
  853.         LFOGeneratorKeyUpSustain1(State->PitchLFO);
  854.  
  855.         if (State->LoopState == eRepeatingLoop1)
  856.             {
  857.                 if (State->Loop2Start != State->Loop2End)
  858.                     {
  859.                         State->LoopState = eRepeatingLoop2;
  860.                         State->CurrentLoopEnd = State->Loop2End;
  861.                         State->CurrentLoopLength = State->Loop2End - State->Loop2Start;
  862.                     }
  863.                 else if (State->Loop3Start != State->Loop3End)
  864.                     {
  865.                         State->LoopState = eRepeatingLoop3;
  866.                         State->CurrentLoopEnd = State->Loop3End;
  867.                         State->CurrentLoopLength = State->Loop3End - State->Loop3Start;
  868.                     }
  869.                 else
  870.                     {
  871.                         State->LoopState = eNoLoop;
  872.                         State->CurrentLoopEnd = State->NumFrames;
  873.                         State->CurrentLoopLength = 0;
  874.                     }
  875.             }
  876.     }
  877.  
  878.  
  879. /* send a key-up signal to one of the oscillators */
  880. void                                    SampleKeyUpSustain2(SampleStateRec* State)
  881.     {
  882.         CheckPtrExistence(State);
  883.         CheckValidSampleState(State);
  884.  
  885.         LFOGeneratorKeyUpSustain2(State->LoudnessLFOGenerator);
  886.         EnvelopeKeyUpSustain2(State->SampleLoudnessEnvelope);
  887.         LFOGeneratorKeyUpSustain2(State->PitchLFO);
  888.  
  889.         if (/*(State->LoopState == eRepeatingLoop1)*/
  890.             /*||*/ (State->LoopState == eRepeatingLoop2))
  891.             {
  892.                 if (State->Loop3Start != State->Loop3End)
  893.                     {
  894.                         State->LoopState = eRepeatingLoop3;
  895.                         State->CurrentLoopEnd = State->Loop3End;
  896.                         State->CurrentLoopLength = State->Loop3End - State->Loop3Start;
  897.                     }
  898.                 else
  899.                     {
  900.                         State->LoopState = eNoLoop;
  901.                         State->CurrentLoopEnd = State->NumFrames;
  902.                         State->CurrentLoopLength = 0;
  903.                     }
  904.             }
  905.     }
  906.  
  907.  
  908. /* send a key-up signal to one of the oscillators */
  909. void                                    SampleKeyUpSustain3(SampleStateRec* State)
  910.     {
  911.         CheckPtrExistence(State);
  912.         CheckValidSampleState(State);
  913.  
  914.         LFOGeneratorKeyUpSustain3(State->LoudnessLFOGenerator);
  915.         EnvelopeKeyUpSustain3(State->SampleLoudnessEnvelope);
  916.         LFOGeneratorKeyUpSustain3(State->PitchLFO);
  917.  
  918.         if (/*(State->LoopState == eRepeatingLoop1)*/
  919.             /*|| (State->LoopState == eRepeatingLoop2)*/
  920.             /*||*/ (State->LoopState == eRepeatingLoop3))
  921.             {
  922.                 State->LoopState = eNoLoop;
  923.                 State->CurrentLoopEnd = State->NumFrames;
  924.                 State->CurrentLoopLength = 0;
  925.             }
  926.     }
  927.  
  928.  
  929. /* restart a sample oscillator.  this is used for tie continuations */
  930. void                                    RestartSampleState(SampleStateRec* State,
  931.                                                 float NewFreqMultisampling, float NewAccent1, float NewAccent2,
  932.                                                 float NewAccent3, float NewAccent4, float NewLoudness,
  933.                                                 float NewHurryUp, MyBoolean RetriggerEnvelopes,
  934.                                                 float NewStereoPosition, float NewInitialFrequency,
  935.                                                 float PitchDisplacementDepthLimit,
  936.                                                 float PitchDisplacementRateLimit,
  937.                                                 long PitchDisplacementStartPoint)
  938.     {
  939.         CheckPtrExistence(State);
  940.         CheckValidSampleState(State);
  941.  
  942.         NewStereoPosition += State->Template.StereoBias;
  943.         if (NewStereoPosition < -1)
  944.             {
  945.                 NewStereoPosition = -1;
  946.             }
  947.         else if (NewStereoPosition > 1)
  948.             {
  949.                 NewStereoPosition = 1;
  950.             }
  951.         State->Panning = Double2FastFixed(NewStereoPosition);
  952.  
  953.         State->NoteLoudnessScaling = NewLoudness * State->Template.OverallOscillatorLoudness;
  954.  
  955.         EnvelopeRetriggerFromOrigin(State->SampleLoudnessEnvelope,NewAccent1,NewAccent2,
  956.             NewAccent3,NewAccent4,NewInitialFrequency,1,NewHurryUp,
  957.             State->Template.EnvelopeTicksPerSecond,RetriggerEnvelopes);
  958.         LFOGeneratorRetriggerFromOrigin(State->LoudnessLFOGenerator,NewAccent1,
  959.             NewAccent2,NewAccent3,NewAccent4,NewInitialFrequency,NewHurryUp,1,1,
  960.             RetriggerEnvelopes);
  961.         LFOGeneratorRetriggerFromOrigin(State->PitchLFO,NewAccent1,
  962.             NewAccent2,NewAccent3,NewAccent4,NewInitialFrequency,NewHurryUp,
  963.             PitchDisplacementDepthLimit,PitchDisplacementRateLimit,
  964.             RetriggerEnvelopes);
  965.         if (RetriggerEnvelopes)
  966.             {
  967.                 State->PitchLFOStartCountdown = PitchDisplacementStartPoint;
  968.             }
  969.          else
  970.             {
  971.                 State->PitchLFOStartCountdown = -1;
  972.             }
  973.     }
  974.  
  975.  
  976. /* generate a sequence of samples (called for each envelope clock) */
  977. void                                    SampleGenSamples(SampleStateRec* State,
  978.                                                 long SampleCount, largefixedsigned* RawBuffer)
  979.     {
  980.         CheckPtrExistence(State);
  981.         CheckValidSampleState(State);
  982.  
  983.         if (State->PreStartCountdown > 0)
  984.             {
  985.                 return;
  986.             }
  987.         if (State->LoopState != eSampleFinished)
  988.             {
  989.                 (*State->SampleGenSamples)(State,SampleCount,RawBuffer);
  990.             }
  991.     }
  992.  
  993.  
  994. /* find out if the sample oscillator has finished */
  995. MyBoolean                            SampleIsItFinished(SampleStateRec* State)
  996.     {
  997.         CheckPtrExistence(State);
  998.         CheckValidSampleState(State);
  999.  
  1000.         /* we are finished when one of the following conditions is met: */
  1001.         /*  - output volume is zero AND loudness envelope is finished */
  1002.         /*  - we have run off the end of the sample */
  1003.         /*  - we are not generating any signal */
  1004.         if (!State->SampleWasDefined)
  1005.             {
  1006.                 return True;
  1007.             }
  1008.         if (State->LoopState == eSampleFinished)
  1009.             {
  1010.                 return True;
  1011.             }
  1012.         if (IsEnvelopeAtEnd(State->SampleLoudnessEnvelope))
  1013.             {
  1014.                 if (State->Template.StereoPlayback == eSampleStereo)
  1015.                     {
  1016.                         if ((State->LeftLoudness == 0) && (State->RightLoudness == 0))
  1017.                             {
  1018.                                 return True;
  1019.                             }
  1020.                     }
  1021.                  else
  1022.                     {
  1023.                         if (State->OverallLoudness == 0)
  1024.                             {
  1025.                                 return True;
  1026.                             }
  1027.                     }
  1028.             }
  1029.  
  1030.         return False;
  1031.     }
  1032.  
  1033.  
  1034. static void                        Sample_MonoOut_MonoSamp_8BitIn_NoTime(SampleStateRec* State,
  1035.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1036.     {
  1037.         LongLongRec                    LocalSamplePosition;
  1038.         LongLongRec                    LocalSamplePositionDifferential;
  1039.         long                                LocalCurrentLoopEnd;
  1040.         FastFixedType                LocalOverallLoudness;
  1041.         signed char*                SampleData;
  1042.  
  1043.         LocalOverallLoudness = State->OverallLoudness;
  1044.         LocalSamplePosition = State->SamplePosition;
  1045.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1046.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1047.         SampleData = (signed char*)State->Data;
  1048.  
  1049.         while (SampleCount > 0)
  1050.             {
  1051.                 PRNGCHK(SampleData,&(SampleData[LongLongHighHalf(LocalSamplePosition)]),
  1052.                     sizeof(SampleData[LongLongHighHalf(LocalSamplePosition)]));
  1053.                 *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalOverallLoudness,
  1054.                     SampleData[LongLongHighHalf(LocalSamplePosition)]);
  1055.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1056.              CheapDoLoop:
  1057.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1058.                     {
  1059.                         if (State->LoopState != eNoLoop)
  1060.                             {
  1061.                                 /* handle loop */
  1062.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1063.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1064.                                 goto CheapDoLoop;
  1065.                             }
  1066.                          else
  1067.                             {
  1068.                                 /* end of sample -- terminate */
  1069.                                 State->LoopState = eSampleFinished;
  1070.                                 goto BreakLoopPoint;
  1071.                             }
  1072.                     }
  1073.                 SampleCount -= 1;
  1074.             }
  1075.      BreakLoopPoint:
  1076.         ;
  1077.  
  1078.         State->SamplePosition = LocalSamplePosition;
  1079.     }
  1080.  
  1081.  
  1082. static void                        Sample_StereoOut_MonoSamp_8BitIn_NoTime(SampleStateRec* State,
  1083.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1084.     {
  1085.         LongLongRec                    LocalSamplePosition;
  1086.         LongLongRec                    LocalSamplePositionDifferential;
  1087.         long                                LocalCurrentLoopEnd;
  1088.         FastFixedType                LocalLeftLoudness;
  1089.         FastFixedType                LocalRightLoudness;
  1090.         signed char*                SampleData;
  1091.  
  1092.         LocalLeftLoudness = State->LeftLoudness;
  1093.         LocalRightLoudness = State->RightLoudness;
  1094.         LocalSamplePosition = State->SamplePosition;
  1095.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1096.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1097.         SampleData = (signed char*)State->Data;
  1098.  
  1099.         while (SampleCount > 0)
  1100.             {
  1101.                 signed long                    SamplePoint;
  1102.  
  1103.                 PRNGCHK(SampleData,&(SampleData[LongLongHighHalf(LocalSamplePosition)]),
  1104.                     sizeof(SampleData[LongLongHighHalf(LocalSamplePosition)]));
  1105.                 SamplePoint = SampleData[LongLongHighHalf(LocalSamplePosition)];
  1106.                 *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalLeftLoudness,SamplePoint);
  1107.                 *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalRightLoudness,SamplePoint);
  1108.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1109.              CheapDoLoop:
  1110.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1111.                     {
  1112.                         if (State->LoopState != eNoLoop)
  1113.                             {
  1114.                                 /* handle loop */
  1115.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1116.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1117.                                 goto CheapDoLoop;
  1118.                             }
  1119.                          else
  1120.                             {
  1121.                                 /* end of sample -- terminate */
  1122.                                 State->LoopState = eSampleFinished;
  1123.                                 goto BreakLoopPoint;
  1124.                             }
  1125.                     }
  1126.                 SampleCount -= 1;
  1127.             }
  1128.      BreakLoopPoint:
  1129.         ;
  1130.  
  1131.         State->SamplePosition = LocalSamplePosition;
  1132.     }
  1133.  
  1134.  
  1135. static void                        Sample_MonoOut_StereoSamp_8BitIn_NoTime(SampleStateRec* State,
  1136.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1137.     {
  1138.         LongLongRec                    LocalSamplePosition;
  1139.         LongLongRec                    LocalSamplePositionDifferential;
  1140.         long                                LocalCurrentLoopEnd;
  1141.         FastFixedType                LocalOverallLoudness;
  1142.         signed char*                SampleData;
  1143.  
  1144.         LocalOverallLoudness = State->OverallLoudness;
  1145.         LocalSamplePosition = State->SamplePosition;
  1146.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1147.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1148.         SampleData = (signed char*)State->Data;
  1149.  
  1150.         while (SampleCount > 0)
  1151.             {
  1152.                 PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]),
  1153.                     sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]));
  1154.                 PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]),
  1155.                     sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]));
  1156.                 *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalOverallLoudness,
  1157.                     ((signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]
  1158.                     + (signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]) >> 1);
  1159.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1160.              CheapDoLoop:
  1161.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1162.                     {
  1163.                         if (State->LoopState != eNoLoop)
  1164.                             {
  1165.                                 /* handle loop */
  1166.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1167.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1168.                                 goto CheapDoLoop;
  1169.                             }
  1170.                          else
  1171.                             {
  1172.                                 /* end of sample -- terminate */
  1173.                                 State->LoopState = eSampleFinished;
  1174.                                 goto BreakLoopPoint;
  1175.                             }
  1176.                     }
  1177.                 SampleCount -= 1;
  1178.             }
  1179.      BreakLoopPoint:
  1180.         ;
  1181.  
  1182.         State->SamplePosition = LocalSamplePosition;
  1183.     }
  1184.  
  1185.  
  1186. static void                        Sample_StereoOut_StereoSamp_8BitIn_NoTime(SampleStateRec* State,
  1187.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1188.     {
  1189.         LongLongRec                    LocalSamplePosition;
  1190.         LongLongRec                    LocalSamplePositionDifferential;
  1191.         long                                LocalCurrentLoopEnd;
  1192.         FastFixedType                LocalLeftLoudness;
  1193.         FastFixedType                LocalRightLoudness;
  1194.         signed char*                SampleData;
  1195.  
  1196.         LocalLeftLoudness = State->LeftLoudness;
  1197.         LocalRightLoudness = State->RightLoudness;
  1198.         LocalSamplePosition = State->SamplePosition;
  1199.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1200.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1201.         SampleData = (signed char*)State->Data;
  1202.  
  1203.         while (SampleCount > 0)
  1204.             {
  1205.                 PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]),
  1206.                     sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]));
  1207.                 *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalLeftLoudness,
  1208.                     (signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]);
  1209.                 PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]),
  1210.                     sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]));
  1211.                 *(RawBuffer++) += FastFixedTimes8BitTo24Bit(LocalRightLoudness,
  1212.                     (signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]);
  1213.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1214.              CheapDoLoop:
  1215.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1216.                     {
  1217.                         if (State->LoopState != eNoLoop)
  1218.                             {
  1219.                                 /* handle loop */
  1220.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1221.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1222.                                 goto CheapDoLoop;
  1223.                             }
  1224.                          else
  1225.                             {
  1226.                                 /* end of sample -- terminate */
  1227.                                 State->LoopState = eSampleFinished;
  1228.                                 goto BreakLoopPoint;
  1229.                             }
  1230.                     }
  1231.                 SampleCount -= 1;
  1232.             }
  1233.      BreakLoopPoint:
  1234.         ;
  1235.  
  1236.         State->SamplePosition = LocalSamplePosition;
  1237.     }
  1238.  
  1239.  
  1240. static void                        Sample_MonoOut_MonoSamp_16BitIn_NoTime(SampleStateRec* State,
  1241.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1242.     {
  1243.         LongLongRec                    LocalSamplePosition;
  1244.         LongLongRec                    LocalSamplePositionDifferential;
  1245.         long                                LocalCurrentLoopEnd;
  1246.         FastFixedType                LocalOverallLoudness;
  1247.         signed short*                SampleData;
  1248.  
  1249.         LocalOverallLoudness = State->OverallLoudness;
  1250.         LocalSamplePosition = State->SamplePosition;
  1251.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1252.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1253.         SampleData = (signed short*)State->Data;
  1254.  
  1255.         while (SampleCount > 0)
  1256.             {
  1257.                 PRNGCHK(SampleData,&(SampleData[LongLongHighHalf(LocalSamplePosition)]),
  1258.                     sizeof(SampleData[LongLongHighHalf(LocalSamplePosition)]));
  1259.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
  1260.                     SampleData[LongLongHighHalf(LocalSamplePosition)]);
  1261.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1262.              CheapDoLoop:
  1263.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1264.                     {
  1265.                         if (State->LoopState != eNoLoop)
  1266.                             {
  1267.                                 /* handle loop */
  1268.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1269.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1270.                                 goto CheapDoLoop;
  1271.                             }
  1272.                          else
  1273.                             {
  1274.                                 /* end of sample -- terminate */
  1275.                                 State->LoopState = eSampleFinished;
  1276.                                 goto BreakLoopPoint;
  1277.                             }
  1278.                     }
  1279.                 SampleCount -= 1;
  1280.             }
  1281.      BreakLoopPoint:
  1282.         ;
  1283.  
  1284.         State->SamplePosition = LocalSamplePosition;
  1285.     }
  1286.  
  1287.  
  1288. static void                        Sample_StereoOut_MonoSamp_16BitIn_NoTime(SampleStateRec* State,
  1289.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1290.     {
  1291.         LongLongRec                    LocalSamplePosition;
  1292.         LongLongRec                    LocalSamplePositionDifferential;
  1293.         long                                LocalCurrentLoopEnd;
  1294.         FastFixedType                LocalLeftLoudness;
  1295.         FastFixedType                LocalRightLoudness;
  1296.         signed short*                SampleData;
  1297.  
  1298.         LocalLeftLoudness = State->LeftLoudness;
  1299.         LocalRightLoudness = State->RightLoudness;
  1300.         LocalSamplePosition = State->SamplePosition;
  1301.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1302.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1303.         SampleData = (signed short*)State->Data;
  1304.  
  1305.         while (SampleCount > 0)
  1306.             {
  1307.                 signed long                    SamplePoint;
  1308.  
  1309.                 PRNGCHK(SampleData,&(SampleData[LongLongHighHalf(LocalSamplePosition)]),
  1310.                     sizeof(SampleData[LongLongHighHalf(LocalSamplePosition)]));
  1311.                 SamplePoint = SampleData[LongLongHighHalf(LocalSamplePosition)];
  1312.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,SamplePoint);
  1313.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,SamplePoint);
  1314.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1315.              CheapDoLoop:
  1316.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1317.                     {
  1318.                         if (State->LoopState != eNoLoop)
  1319.                             {
  1320.                                 /* handle loop */
  1321.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1322.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1323.                                 goto CheapDoLoop;
  1324.                             }
  1325.                          else
  1326.                             {
  1327.                                 /* end of sample -- terminate */
  1328.                                 State->LoopState = eSampleFinished;
  1329.                                 goto BreakLoopPoint;
  1330.                             }
  1331.                     }
  1332.                 SampleCount -= 1;
  1333.             }
  1334.      BreakLoopPoint:
  1335.         ;
  1336.  
  1337.         State->SamplePosition = LocalSamplePosition;
  1338.     }
  1339.  
  1340.  
  1341. static void                        Sample_MonoOut_StereoSamp_16BitIn_NoTime(SampleStateRec* State,
  1342.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1343.     {
  1344.         LongLongRec                    LocalSamplePosition;
  1345.         LongLongRec                    LocalSamplePositionDifferential;
  1346.         long                                LocalCurrentLoopEnd;
  1347.         FastFixedType                LocalOverallLoudness;
  1348.         signed short*                SampleData;
  1349.  
  1350.         LocalOverallLoudness = State->OverallLoudness;
  1351.         LocalSamplePosition = State->SamplePosition;
  1352.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1353.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1354.         SampleData = (signed short*)State->Data;
  1355.  
  1356.         while (SampleCount > 0)
  1357.             {
  1358.                 PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]),
  1359.                     sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]));
  1360.                 PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]),
  1361.                     sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]));
  1362.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,
  1363.                     ((signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]
  1364.                     + (signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]) >> 1);
  1365.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1366.              CheapDoLoop:
  1367.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1368.                     {
  1369.                         if (State->LoopState != eNoLoop)
  1370.                             {
  1371.                                 /* handle loop */
  1372.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1373.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1374.                                 goto CheapDoLoop;
  1375.                             }
  1376.                          else
  1377.                             {
  1378.                                 /* end of sample -- terminate */
  1379.                                 State->LoopState = eSampleFinished;
  1380.                                 goto BreakLoopPoint;
  1381.                             }
  1382.                     }
  1383.                 SampleCount -= 1;
  1384.             }
  1385.      BreakLoopPoint:
  1386.         ;
  1387.  
  1388.         State->SamplePosition = LocalSamplePosition;
  1389.     }
  1390.  
  1391.  
  1392. static void                        Sample_StereoOut_StereoSamp_16BitIn_NoTime(SampleStateRec* State,
  1393.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1394.     {
  1395.         LongLongRec                    LocalSamplePosition;
  1396.         LongLongRec                    LocalSamplePositionDifferential;
  1397.         long                                LocalCurrentLoopEnd;
  1398.         FastFixedType                LocalLeftLoudness;
  1399.         FastFixedType                LocalRightLoudness;
  1400.         signed short*                SampleData;
  1401.  
  1402.         LocalLeftLoudness = State->LeftLoudness;
  1403.         LocalRightLoudness = State->RightLoudness;
  1404.         LocalSamplePosition = State->SamplePosition;
  1405.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1406.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1407.         SampleData = (signed short*)State->Data;
  1408.  
  1409.         while (SampleCount > 0)
  1410.             {
  1411.                 PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]),
  1412.                     sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]));
  1413.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,
  1414.                     (signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 0]);
  1415.                 PRNGCHK(SampleData,&(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]),
  1416.                     sizeof(SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]));
  1417.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,
  1418.                     (signed long)SampleData[2 * LongLongHighHalf(LocalSamplePosition) + 1]);
  1419.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1420.              CheapDoLoop:
  1421.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1422.                     {
  1423.                         if (State->LoopState != eNoLoop)
  1424.                             {
  1425.                                 /* handle loop */
  1426.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1427.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1428.                                 goto CheapDoLoop;
  1429.                             }
  1430.                          else
  1431.                             {
  1432.                                 /* end of sample -- terminate */
  1433.                                 State->LoopState = eSampleFinished;
  1434.                                 goto BreakLoopPoint;
  1435.                             }
  1436.                     }
  1437.                 SampleCount -= 1;
  1438.             }
  1439.      BreakLoopPoint:
  1440.         ;
  1441.  
  1442.         State->SamplePosition = LocalSamplePosition;
  1443.     }
  1444.  
  1445.  
  1446. static void                        Sample_MonoOut_MonoSamp_8BitIn_YesTime(SampleStateRec* State,
  1447.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1448.     {
  1449.         LongLongRec                    LocalSamplePosition;
  1450.         LongLongRec                    LocalSamplePositionDifferential;
  1451.         long                                LocalCurrentLoopEnd;
  1452.         FastFixedType                LocalOverallLoudness;
  1453.         signed char*                SampleData;
  1454.  
  1455.         LocalOverallLoudness = State->OverallLoudness;
  1456.         LocalSamplePosition = State->SamplePosition;
  1457.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1458.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1459.         SampleData = (signed char*)State->Data;
  1460.  
  1461.         while (SampleCount > 0)
  1462.             {
  1463.                 FastFixedType                LeftWeight;
  1464.                 long                                ArraySubscript;
  1465.                 signed long                    LeftValue;
  1466.                 signed long                    RightValue;
  1467.  
  1468.                 /* L+F(R-L) */
  1469.                 LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
  1470.                 ArraySubscript = LongLongHighHalf(LocalSamplePosition);
  1471.                 PRNGCHK(SampleData,&(SampleData[ArraySubscript]),
  1472.                     sizeof(SampleData[ArraySubscript]));
  1473.                 LeftValue = ((signed long)SampleData[ArraySubscript]) << 8; /* convert to 16-bit */
  1474.                 PRNGCHK(SampleData,&(SampleData[ArraySubscript + 1]),
  1475.                     sizeof(SampleData[ArraySubscript + 1]));
  1476.                 RightValue = ((signed long)SampleData[ArraySubscript + 1]) << 8; /* to 16-bit */
  1477.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
  1478.                     + ((LeftWeight * (RightValue - LeftValue)) >> 15));
  1479.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1480.              CheapDoLoop:
  1481.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1482.                     {
  1483.                         if (State->LoopState != eNoLoop)
  1484.                             {
  1485.                                 /* handle loop */
  1486.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1487.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1488.                                 goto CheapDoLoop;
  1489.                             }
  1490.                          else
  1491.                             {
  1492.                                 /* end of sample -- terminate */
  1493.                                 State->LoopState = eSampleFinished;
  1494.                                 goto BreakLoopPoint;
  1495.                             }
  1496.                     }
  1497.                 SampleCount -= 1;
  1498.             }
  1499.      BreakLoopPoint:
  1500.         ;
  1501.  
  1502.         State->SamplePosition = LocalSamplePosition;
  1503.     }
  1504.  
  1505.  
  1506. static void                        Sample_StereoOut_MonoSamp_8BitIn_YesTime(SampleStateRec* State,
  1507.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1508.     {
  1509.         LongLongRec                    LocalSamplePosition;
  1510.         LongLongRec                    LocalSamplePositionDifferential;
  1511.         long                                LocalCurrentLoopEnd;
  1512.         FastFixedType                LocalLeftLoudness;
  1513.         FastFixedType                LocalRightLoudness;
  1514.         signed char*                SampleData;
  1515.  
  1516.         LocalLeftLoudness = State->LeftLoudness;
  1517.         LocalRightLoudness = State->RightLoudness;
  1518.         LocalSamplePosition = State->SamplePosition;
  1519.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1520.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1521.         SampleData = (signed char*)State->Data;
  1522.  
  1523.         while (SampleCount > 0)
  1524.             {
  1525.                 FastFixedType                LeftWeight;
  1526.                 long                                ArraySubscript;
  1527.                 signed long                    LeftValue;
  1528.                 signed long                    RightValue;
  1529.                 signed long                    CombinedValue;
  1530.  
  1531.                 /* L+F(R-L) */
  1532.                 LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
  1533.                 ArraySubscript = LongLongHighHalf(LocalSamplePosition);
  1534.                 PRNGCHK(SampleData,&(SampleData[ArraySubscript]),
  1535.                     sizeof(SampleData[ArraySubscript]));
  1536.                 LeftValue = ((signed long)SampleData[ArraySubscript]) << 8; /* convert to 16-bit */
  1537.                 PRNGCHK(SampleData,&(SampleData[ArraySubscript + 1]),
  1538.                     sizeof(SampleData[ArraySubscript + 1]));
  1539.                 RightValue = ((signed long)SampleData[ArraySubscript + 1]) << 8; /* to 16-bit */
  1540.                 CombinedValue = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
  1541.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,CombinedValue);
  1542.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,CombinedValue);
  1543.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1544.              CheapDoLoop:
  1545.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1546.                     {
  1547.                         if (State->LoopState != eNoLoop)
  1548.                             {
  1549.                                 /* handle loop */
  1550.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1551.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1552.                                 goto CheapDoLoop;
  1553.                             }
  1554.                          else
  1555.                             {
  1556.                                 /* end of sample -- terminate */
  1557.                                 State->LoopState = eSampleFinished;
  1558.                                 goto BreakLoopPoint;
  1559.                             }
  1560.                     }
  1561.                 SampleCount -= 1;
  1562.             }
  1563.      BreakLoopPoint:
  1564.         ;
  1565.  
  1566.         State->SamplePosition = LocalSamplePosition;
  1567.     }
  1568.  
  1569.  
  1570. static void                        Sample_MonoOut_StereoSamp_8BitIn_YesTime(SampleStateRec* State,
  1571.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1572.     {
  1573.         LongLongRec                    LocalSamplePosition;
  1574.         LongLongRec                    LocalSamplePositionDifferential;
  1575.         long                                LocalCurrentLoopEnd;
  1576.         FastFixedType                LocalOverallLoudness;
  1577.         signed char*                SampleData;
  1578.  
  1579.         LocalOverallLoudness = State->OverallLoudness;
  1580.         LocalSamplePosition = State->SamplePosition;
  1581.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1582.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1583.         SampleData = (signed char*)State->Data;
  1584.  
  1585.         while (SampleCount > 0)
  1586.             {
  1587.                 FastFixedType                LeftWeight;
  1588.                 long                                ArraySubscript;
  1589.                 signed long                    LeftValue;
  1590.                 signed long                    RightValue;
  1591.  
  1592.                 /* L+F(R-L) */
  1593.                 LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
  1594.                 ArraySubscript = LongLongHighHalf(LocalSamplePosition);
  1595.                 PRNGCHK(SampleData,&(SampleData[2 * ArraySubscript + 0]),
  1596.                     sizeof(SampleData[2 * ArraySubscript + 0]));
  1597.                 PRNGCHK(SampleData,&(SampleData[2 * ArraySubscript + 1]),
  1598.                     sizeof(SampleData[2 * ArraySubscript + 1]));
  1599.                 LeftValue = ((signed long)SampleData[2 * ArraySubscript + 0]
  1600.                     + (signed long)SampleData[2 * ArraySubscript + 1]) << 7; /* convert to 16-bit */
  1601.                 PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1) + 0]),
  1602.                     sizeof(SampleData[2 * (ArraySubscript + 1) + 0]));
  1603.                 PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1) + 1]),
  1604.                     sizeof(SampleData[2 * (ArraySubscript + 1) + 1]));
  1605.                 RightValue = ((signed long)SampleData[2 * (ArraySubscript + 1) + 0]
  1606.                     + (signed long)SampleData[2 * (ArraySubscript + 1) + 1]) << 7; /* to 16-bit */
  1607.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
  1608.                     + ((LeftWeight * (RightValue - LeftValue)) >> 15));
  1609.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1610.              CheapDoLoop:
  1611.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1612.                     {
  1613.                         if (State->LoopState != eNoLoop)
  1614.                             {
  1615.                                 /* handle loop */
  1616.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1617.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1618.                                 goto CheapDoLoop;
  1619.                             }
  1620.                          else
  1621.                             {
  1622.                                 /* end of sample -- terminate */
  1623.                                 State->LoopState = eSampleFinished;
  1624.                                 goto BreakLoopPoint;
  1625.                             }
  1626.                     }
  1627.                 SampleCount -= 1;
  1628.             }
  1629.      BreakLoopPoint:
  1630.         ;
  1631.  
  1632.         State->SamplePosition = LocalSamplePosition;
  1633.     }
  1634.  
  1635.  
  1636. static void                        Sample_StereoOut_StereoSamp_8BitIn_YesTime(SampleStateRec* State,
  1637.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1638.     {
  1639.         LongLongRec                    LocalSamplePosition;
  1640.         LongLongRec                    LocalSamplePositionDifferential;
  1641.         long                                LocalCurrentLoopEnd;
  1642.         FastFixedType                LocalLeftLoudness;
  1643.         FastFixedType                LocalRightLoudness;
  1644.         signed char*                SampleData;
  1645.  
  1646.         LocalLeftLoudness = State->LeftLoudness;
  1647.         LocalRightLoudness = State->RightLoudness;
  1648.         LocalSamplePosition = State->SamplePosition;
  1649.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1650.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1651.         SampleData = (signed char*)State->Data;
  1652.  
  1653.         while (SampleCount > 0)
  1654.             {
  1655.                 FastFixedType                LeftWeight;
  1656.                 long                                ArraySubscript;
  1657.                 signed long                    LeftValue;
  1658.                 signed long                    RightValue;
  1659.  
  1660.                 /* L+F(R-L) */
  1661.                 LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
  1662.                 ArraySubscript = LongLongHighHalf(LocalSamplePosition);
  1663.                 PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 0)]),
  1664.                     sizeof(SampleData[2 * (ArraySubscript + 0)]));
  1665.                 LeftValue = ((signed long)SampleData[2 * (ArraySubscript + 0)]) << 8; /* convert to 16-bit */
  1666.                 PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1)]),
  1667.                     sizeof(SampleData[2 * (ArraySubscript + 1)]));
  1668.                 RightValue = ((signed long)SampleData[2 * (ArraySubscript + 1)]) << 8; /* to 16-bit */
  1669.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,LeftValue
  1670.                     + ((LeftWeight * (RightValue - LeftValue)) >> 15));
  1671.                 PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 0) + 1]),
  1672.                     sizeof(SampleData[2 * (ArraySubscript + 0) + 1]));
  1673.                 LeftValue = ((signed long)SampleData[2 * (ArraySubscript + 0) + 1]) << 8; /* convert to 16-bit */
  1674.                 PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1) + 1]),
  1675.                     sizeof(SampleData[2 * (ArraySubscript + 1) + 1]));
  1676.                 RightValue = ((signed long)SampleData[2 * (ArraySubscript + 1) + 1]) << 8; /* to 16-bit */
  1677.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,LeftValue
  1678.                     + ((LeftWeight * (RightValue - LeftValue)) >> 15));
  1679.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1680.              CheapDoLoop:
  1681.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1682.                     {
  1683.                         if (State->LoopState != eNoLoop)
  1684.                             {
  1685.                                 /* handle loop */
  1686.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1687.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1688.                                 goto CheapDoLoop;
  1689.                             }
  1690.                          else
  1691.                             {
  1692.                                 /* end of sample -- terminate */
  1693.                                 State->LoopState = eSampleFinished;
  1694.                                 goto BreakLoopPoint;
  1695.                             }
  1696.                     }
  1697.                 SampleCount -= 1;
  1698.             }
  1699.      BreakLoopPoint:
  1700.         ;
  1701.  
  1702.         State->SamplePosition = LocalSamplePosition;
  1703.     }
  1704.  
  1705.  
  1706. static void                        Sample_MonoOut_MonoSamp_16BitIn_YesTime(SampleStateRec* State,
  1707.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1708.     {
  1709.         LongLongRec                    LocalSamplePosition;
  1710.         LongLongRec                    LocalSamplePositionDifferential;
  1711.         long                                LocalCurrentLoopEnd;
  1712.         FastFixedType                LocalOverallLoudness;
  1713.         signed short*                SampleData;
  1714.  
  1715.         LocalOverallLoudness = State->OverallLoudness;
  1716.         LocalSamplePosition = State->SamplePosition;
  1717.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1718.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1719.         SampleData = (signed short*)State->Data;
  1720.  
  1721.         while (SampleCount > 0)
  1722.             {
  1723.                 FastFixedType                LeftWeight;
  1724.                 long                                ArraySubscript;
  1725.                 signed long                    LeftValue;
  1726.                 signed long                    RightValue;
  1727.  
  1728.                 /* L+F(R-L) */
  1729.                 LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
  1730.                 ArraySubscript = LongLongHighHalf(LocalSamplePosition);
  1731.                 PRNGCHK(SampleData,&(SampleData[ArraySubscript]),
  1732.                     sizeof(SampleData[ArraySubscript]));
  1733.                 LeftValue = SampleData[ArraySubscript];
  1734.                 PRNGCHK(SampleData,&(SampleData[ArraySubscript + 1]),
  1735.                     sizeof(SampleData[ArraySubscript + 1]));
  1736.                 RightValue = SampleData[ArraySubscript + 1];
  1737.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
  1738.                     + ((LeftWeight * (RightValue - LeftValue)) >> 15));
  1739.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1740.              CheapDoLoop:
  1741.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1742.                     {
  1743.                         if (State->LoopState != eNoLoop)
  1744.                             {
  1745.                                 /* handle loop */
  1746.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1747.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1748.                                 goto CheapDoLoop;
  1749.                             }
  1750.                          else
  1751.                             {
  1752.                                 /* end of sample -- terminate */
  1753.                                 State->LoopState = eSampleFinished;
  1754.                                 goto BreakLoopPoint;
  1755.                             }
  1756.                     }
  1757.                 SampleCount -= 1;
  1758.             }
  1759.      BreakLoopPoint:
  1760.         ;
  1761.  
  1762.         State->SamplePosition = LocalSamplePosition;
  1763.     }
  1764.  
  1765.  
  1766. static void                        Sample_StereoOut_MonoSamp_16BitIn_YesTime(SampleStateRec* State,
  1767.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1768.     {
  1769.         LongLongRec                    LocalSamplePosition;
  1770.         LongLongRec                    LocalSamplePositionDifferential;
  1771.         long                                LocalCurrentLoopEnd;
  1772.         FastFixedType                LocalLeftLoudness;
  1773.         FastFixedType                LocalRightLoudness;
  1774.         signed short*                SampleData;
  1775.  
  1776.         LocalLeftLoudness = State->LeftLoudness;
  1777.         LocalRightLoudness = State->RightLoudness;
  1778.         LocalSamplePosition = State->SamplePosition;
  1779.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1780.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1781.         SampleData = (signed short*)State->Data;
  1782.  
  1783.         while (SampleCount > 0)
  1784.             {
  1785.                 FastFixedType                LeftWeight;
  1786.                 long                                ArraySubscript;
  1787.                 signed long                    LeftValue;
  1788.                 signed long                    RightValue;
  1789.                 signed long                    CombinedValue;
  1790.  
  1791.                 /* L+F(R-L) */
  1792.                 LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
  1793.                 ArraySubscript = LongLongHighHalf(LocalSamplePosition);
  1794.                 PRNGCHK(SampleData,&(SampleData[ArraySubscript]),
  1795.                     sizeof(SampleData[ArraySubscript]));
  1796.                 LeftValue = SampleData[ArraySubscript];
  1797.                 PRNGCHK(SampleData,&(SampleData[ArraySubscript + 1]),
  1798.                     sizeof(SampleData[ArraySubscript + 1]));
  1799.                 RightValue = SampleData[ArraySubscript + 1];
  1800.                 CombinedValue = LeftValue + ((LeftWeight * (RightValue - LeftValue)) >> 15);
  1801.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,CombinedValue);
  1802.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,CombinedValue);
  1803.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1804.              CheapDoLoop:
  1805.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1806.                     {
  1807.                         if (State->LoopState != eNoLoop)
  1808.                             {
  1809.                                 /* handle loop */
  1810.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1811.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1812.                                 goto CheapDoLoop;
  1813.                             }
  1814.                          else
  1815.                             {
  1816.                                 /* end of sample -- terminate */
  1817.                                 State->LoopState = eSampleFinished;
  1818.                                 goto BreakLoopPoint;
  1819.                             }
  1820.                     }
  1821.                 SampleCount -= 1;
  1822.             }
  1823.      BreakLoopPoint:
  1824.         ;
  1825.  
  1826.         State->SamplePosition = LocalSamplePosition;
  1827.     }
  1828.  
  1829.  
  1830. static void                        Sample_MonoOut_StereoSamp_16BitIn_YesTime(SampleStateRec* State,
  1831.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1832.     {
  1833.         LongLongRec                    LocalSamplePosition;
  1834.         LongLongRec                    LocalSamplePositionDifferential;
  1835.         long                                LocalCurrentLoopEnd;
  1836.         FastFixedType                LocalOverallLoudness;
  1837.         signed short*                SampleData;
  1838.  
  1839.         LocalOverallLoudness = State->OverallLoudness;
  1840.         LocalSamplePosition = State->SamplePosition;
  1841.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1842.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1843.         SampleData = (signed short*)State->Data;
  1844.  
  1845.         while (SampleCount > 0)
  1846.             {
  1847.                 FastFixedType                LeftWeight;
  1848.                 long                                ArraySubscript;
  1849.                 signed long                    LeftValue;
  1850.                 signed long                    RightValue;
  1851.  
  1852.                 /* L+F(R-L) */
  1853.                 LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
  1854.                 ArraySubscript = LongLongHighHalf(LocalSamplePosition);
  1855.                 PRNGCHK(SampleData,&(SampleData[2 * ArraySubscript + 0]),
  1856.                     sizeof(SampleData[2 * ArraySubscript + 0]));
  1857.                 PRNGCHK(SampleData,&(SampleData[2 * ArraySubscript + 1]),
  1858.                     sizeof(SampleData[2 * ArraySubscript + 1]));
  1859.                 LeftValue = ((signed long)SampleData[2 * ArraySubscript + 0]
  1860.                     + (signed long)SampleData[2 * ArraySubscript + 1]) >> 1;
  1861.                 PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1) + 0]),
  1862.                     sizeof(SampleData[2 * (ArraySubscript + 1) + 0]));
  1863.                 PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1) + 1]),
  1864.                     sizeof(SampleData[2 * (ArraySubscript + 1) + 1]));
  1865.                 RightValue = ((signed long)SampleData[2 * (ArraySubscript + 1) + 0]
  1866.                     + (signed long)SampleData[2 * (ArraySubscript + 1) + 1]) >> 1;
  1867.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalOverallLoudness,LeftValue
  1868.                     + ((LeftWeight * (RightValue - LeftValue)) >> 15));
  1869.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1870.              CheapDoLoop:
  1871.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1872.                     {
  1873.                         if (State->LoopState != eNoLoop)
  1874.                             {
  1875.                                 /* handle loop */
  1876.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1877.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1878.                                 goto CheapDoLoop;
  1879.                             }
  1880.                          else
  1881.                             {
  1882.                                 /* end of sample -- terminate */
  1883.                                 State->LoopState = eSampleFinished;
  1884.                                 goto BreakLoopPoint;
  1885.                             }
  1886.                     }
  1887.                 SampleCount -= 1;
  1888.             }
  1889.      BreakLoopPoint:
  1890.         ;
  1891.  
  1892.         State->SamplePosition = LocalSamplePosition;
  1893.     }
  1894.  
  1895.  
  1896. static void                        Sample_StereoOut_StereoSamp_16BitIn_YesTime(SampleStateRec* State,
  1897.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1898.     {
  1899.         LongLongRec                    LocalSamplePosition;
  1900.         LongLongRec                    LocalSamplePositionDifferential;
  1901.         long                                LocalCurrentLoopEnd;
  1902.         FastFixedType                LocalLeftLoudness;
  1903.         FastFixedType                LocalRightLoudness;
  1904.         signed short*                SampleData;
  1905.  
  1906.         LocalLeftLoudness = State->LeftLoudness;
  1907.         LocalRightLoudness = State->RightLoudness;
  1908.         LocalSamplePosition = State->SamplePosition;
  1909.         LocalSamplePositionDifferential = State->SamplePositionDifferential;
  1910.         LocalCurrentLoopEnd = State->CurrentLoopEnd;
  1911.         SampleData = (signed short*)State->Data;
  1912.  
  1913.         while (SampleCount > 0)
  1914.             {
  1915.                 FastFixedType                LeftWeight;
  1916.                 long                                ArraySubscript;
  1917.                 signed long                    LeftValue;
  1918.                 signed long                    RightValue;
  1919.  
  1920.                 /* L+F(R-L) */
  1921.                 LeftWeight = LongLongLowHalf(LocalSamplePosition) >> (32 - FASTFIXEDPRECISION);
  1922.                 ArraySubscript = LongLongHighHalf(LocalSamplePosition);
  1923.                 PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 0)]),
  1924.                     sizeof(SampleData[2 * (ArraySubscript + 0)]));
  1925.                 LeftValue = SampleData[2 * (ArraySubscript + 0)];
  1926.                 PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1)]),
  1927.                     sizeof(SampleData[2 * (ArraySubscript + 1)]));
  1928.                 RightValue = SampleData[2 * (ArraySubscript + 1)];
  1929.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalLeftLoudness,LeftValue
  1930.                     + ((LeftWeight * (RightValue - LeftValue)) >> 15));
  1931.                 PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 0) + 1]),
  1932.                     sizeof(SampleData[2 * (ArraySubscript + 0) + 1]));
  1933.                 LeftValue = SampleData[2 * (ArraySubscript + 0) + 1];
  1934.                 PRNGCHK(SampleData,&(SampleData[2 * (ArraySubscript + 1) + 1]),
  1935.                     sizeof(SampleData[2 * (ArraySubscript + 1) + 1]));
  1936.                 RightValue = SampleData[2 * (ArraySubscript + 1) + 1];
  1937.                 *(RawBuffer++) += FastFixedTimes16BitTo24Bit(LocalRightLoudness,LeftValue
  1938.                     + ((LeftWeight * (RightValue - LeftValue)) >> 15));
  1939.                 LongLongAdd(&LocalSamplePosition,&LocalSamplePositionDifferential);
  1940.              CheapDoLoop:
  1941.                 if (LongLongHighHalf(LocalSamplePosition) >= LocalCurrentLoopEnd)
  1942.                     {
  1943.                         if (State->LoopState != eNoLoop)
  1944.                             {
  1945.                                 /* handle loop */
  1946.                                 LongLongSetHighHalf(LocalSamplePosition,LongLongHighHalf(
  1947.                                     LocalSamplePosition) - State->CurrentLoopLength);
  1948.                                 goto CheapDoLoop;
  1949.                             }
  1950.                          else
  1951.                             {
  1952.                                 /* end of sample -- terminate */
  1953.                                 State->LoopState = eSampleFinished;
  1954.                                 goto BreakLoopPoint;
  1955.                             }
  1956.                     }
  1957.                 SampleCount -= 1;
  1958.             }
  1959.      BreakLoopPoint:
  1960.         ;
  1961.  
  1962.         State->SamplePosition = LocalSamplePosition;
  1963.     }
  1964.  
  1965.  
  1966. static void                        Sample_NoOutput(SampleStateRec* State,
  1967.                                                 long SampleCount, largefixedsigned* RawBuffer)
  1968.     {
  1969.     }
  1970.